﻿namespace WFBot.Framework.Web.Controllers
{
    using System.Web.Mvc;
    using WFBot.Rtc;
    using System.Linq;
    using WFBot.Framework.Repositories;
    using WFBot.Framework.Domain;
    using WFBot.Framework.Infrastructure;
    using WFBot.Framework.Services;

    public class CommunicatorController : Controller
    {
        private readonly ICommunicationService _communicationService;
        private readonly IVisitorRepository _visitorRepository;
        private readonly IOperatorRepository _operatorRepository;
        private readonly IOperatorService _operatorService;
        private readonly PresenceUpdater _presenceUpdater;

        public CommunicatorController(ICommunicationService communicationService, IVisitorRepository visitorRepository, IOperatorRepository operatorRepository, IOperatorService operatorService, PresenceUpdater presenceUpdater)
        {
            _communicationService = communicationService;
            _visitorRepository = visitorRepository;
            _operatorRepository = operatorRepository;
            _operatorService = operatorService;
            _presenceUpdater = presenceUpdater;

            foreach (var op in _operatorRepository.All())
            {
                _presenceUpdater.AddTarget(op.SipUri);
            }
            _presenceUpdater.Initialize();
        }

        private Visitor FindVisitor(string userid)
        {
            var op = _operatorRepository.GetBySipUri(userid);
            var visitor = _visitorRepository.GetBySessionId(op.CurrentChannel);

            if (visitor == null)
            {
                visitor = new Visitor();
            }

            return visitor;
        }

        [HttpPost]
        public JsonResult Check(string userid)
        {
            var visitor = FindVisitor(userid);
            return Json(visitor);
        }

        public ActionResult Info(string userid)
        {
            ViewData["userId"] = userid;
            ViewData.Model = FindVisitor(userid);
            return View();
        }

        public ActionResult History(string userid)
        {
            ViewData["userId"] = userid;
            ViewData.Model = FindVisitor(userid);
            return View();
        }

        public ActionResult Index(string channel)
        {
            ViewData.Model = channel;
            return View();
        }

        [HttpPost]
        public ActionResult GetAvailability(string sip)
        {
            if (string.IsNullOrWhiteSpace(sip))
            {
                return Json(_presenceUpdater.GetAvailableOps().Count > 0);
            }

            if (_presenceUpdater.GetAvailableOps().Contains(sip))
                return Json(true);
            else
                return Json(false);
        }

        [HttpPost]
        public ActionResult GetAvailableOperator()
        {
            if (_presenceUpdater.GetAvailableOps().Count == 0)
            {
                return Json(null);
            }
            else
            {
                return Json(_presenceUpdater.GetAvailableOps().First());
            }
        }

        [HttpPost]
        public JsonResult Init(string channel)
        {
            var sessionId = channel.Split(';')[0];
            var sip = "sip:" + channel.Split(';')[1];
            var op = _operatorRepository.GetBySipUri(sip);
            op.CurrentChannel = sessionId;
            _operatorService.UpdateCurrentChannel(op, sessionId);
            _communicationService.Mapping[sessionId] = op.DisplayName;

            _communicationService.Initialize();
            _communicationService.Push(new RtcMessage() { Channel = channel, Body = "Bir ziyaretçi var!" });
            return Json(true);
        }

        [HttpPost]
        public JsonResult Push(RtcMessage message)
        {
            _communicationService.Push(message);
            return Json(true);
        }

        [HttpPost]
        public JsonResult Pull(string channel)
        {
            return Json(_communicationService.Pull(channel));
        }

    }
}
